#ifndef UtilsGL_h
#define UtilsGL_h

#pragma comment (lib,"./lib/glew32.lib")

#define _USE_MATH_DEFINES
#include <math.h>
#include <cmath>
#include <SOIL.h>

#ifdef WIN32
#include <windows.h>
#endif

#include <GL/glew.h>
#ifdef WIN32
#include <GL/wglew.h>
#endif

#include <GL/glu.h>

#include <iostream>

//#define USE_OPENGLUT

#ifdef USE_OPENGLUT
#include <GL/openglut.h>

#ifdef _WIN32
#pragma comment (lib,"openglut.lib")
#endif

#else
#include <glut.h>
#endif
#include "mathlib.h"

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

#define INT_INDICE_BUG 32768


inline std::string operator +(const std::string &str, const float f){
	char buff[4096];

	sprintf_s(buff, "%s%f", str.c_str(), f);
	
	return buff;
}

inline std::string operator +(const std::string &str, const int f){
	char buff[4096];

	sprintf_s(buff, "%s%d", str.c_str(), f);

	return buff;
}

inline int GLGetFormatSize(GLuint format){
	switch(format){
		case GL_RGBA8:
		case GL_RGBA:
		case GL_BGRA:
			return 4;
		case GL_RGB8:
		case GL_RGB:
			return 3;
		case GL_RGBA16F_ARB:
			return 8;
		case GL_RGB16F_ARB:
			return 6;
		case GL_RGBA32F_ARB:
			return 16;
		case GL_RGB32F_ARB:
			return 12;
		default:
			return -1;
	}
}

//get gl types from c++
template<class T>
inline int GLGetGLType(){
	return 0;
}

template<>
inline int GLGetGLType<GLfloat>(){
	return GL_FLOAT;
}

template<>
inline int GLGetGLType<GLhalf>(){
	return GL_HALF_FLOAT_NV;
}


/////////Gestion des extensions
class GLExtensionsManager {
	static bool initialized;
public:
	static int initialize();
	static int checkSupported(const char *exts);
};

//////////////////////////////
#endif